package com.xiaozhichao.databafflesys.admin.controller;


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaozhichao.databafflesys.common.domain.CommonConstant;
import com.xiaozhichao.databafflesys.common.domain.ExceptionEnums;
import com.xiaozhichao.databafflesys.common.domain.PageHelper;
import com.xiaozhichao.databafflesys.common.domain.ResultVo;
import com.xiaozhichao.databafflesys.common.utils.MessageValid;
import com.xiaozhichao.databafflesys.repository.model.BaffleConfig;
import com.xiaozhichao.databafflesys.repository.model.BaffleFailTmp;
import com.xiaozhichao.databafflesys.repository.model.BaffleInterface;
import com.xiaozhichao.databafflesys.repository.service.BaffleConfigService;
import com.xiaozhichao.databafflesys.repository.service.BaffleFailTmpService;
import com.xiaozhichao.databafflesys.repository.service.BaffleInterfaceService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author xiaozhichao
 * @since 2021-03-23
 */
@Controller
@RequestMapping("/baffleFailTmp")
public class BaffleFailTmpController {

    @Autowired
    BaffleInterfaceService interfaceService;
    @Autowired
    BaffleFailTmpService failTmpService;
    @Autowired
    BaffleConfigService configService;

    @RequestMapping("/selectPage")
    @ResponseBody
    public ResultVo selectPage(BaffleFailTmp entry, PageHelper helper) {
        IPage<BaffleFailTmp> page = new Page<>(helper.getPage(), helper.getLimit());
        QueryWrapper<BaffleFailTmp> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(Objects.nonNull(entry.getInterfaceId()), BaffleFailTmp::getInterfaceId, entry.getInterfaceId());
        IPage<BaffleFailTmp> pageResult = failTmpService.page(page, wrapper);
        List<BaffleFailTmp> result = pageResult.getRecords();
        Iterator<BaffleFailTmp> iterator = result.iterator();
        JSONArray array = new JSONArray();
        while(iterator.hasNext()){
            BaffleFailTmp next = iterator.next();
            JSONObject obj = JSONObject.parseObject(JSON.toJSONString(next));
            BaffleInterface byId = interfaceService.getById(next.getInterfaceId());
            obj.put("interfaceName",Objects.nonNull(byId) ? byId.getName() : "");
            array.add(obj);

        }
        return ResultVo.getResult(ExceptionEnums.SUCCESS, pageResult.getTotal(), array);
    }

    @RequestMapping("/add")
    @ResponseBody
    public ResultVo add(BaffleFailTmp entry,@RequestParam("tmp") MultipartFile tmpFile) throws Exception {
        // 验证
        BaffleInterface baffleInterface = interfaceService.getById(entry.getInterfaceId());
        if (Objects.isNull(baffleInterface)) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "该接口不存在");
        }
        final String tmpFileName = tmpFile.getOriginalFilename();
        final String resType = baffleInterface.getResType();
        final String resSuffix = tmpFileName.substring(tmpFileName.lastIndexOf(".") + 1);
        if (CommonConstant.file.equals(resType)) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "响应报文格式为文件，不能设置模板");
        }
        if (!resSuffix.equals(resType)) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "响应报文文件格式不匹配");
        }
        String resRead = null;
        try {
            resRead = IoUtil.read(tmpFile.getInputStream(), CommonConstant.utf_8);
        } catch (Exception e) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "响应报文模板文件内容有误");
        }
        if (!MessageValid.valid(resType, resRead)) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "响应报文模板文件内容有误");
        }
        // 上传路径前缀信息
        QueryWrapper<BaffleConfig> wrapperConfig = new QueryWrapper<>();
        wrapperConfig.lambda()
                .eq(true, BaffleConfig::getCode, CommonConstant.message_path_prefix);
        BaffleConfig config = configService.getOne(wrapperConfig);
        if (Objects.isNull(config)) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "报文上传路径前缀未配置");
        }
        String message_path_prefix = config.getNote();

        // 验证接口唯一
        QueryWrapper<BaffleFailTmp> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(Objects.nonNull(entry.getInterfaceId()), BaffleFailTmp::getInterfaceId, entry.getInterfaceId())
                .ne(Objects.nonNull(entry.getId()), BaffleFailTmp::getId, entry.getId());
        int countName = failTmpService.count(wrapper);
        if (countName > 0) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "该接口失败模板已存在");
        }

        // 保存
        failTmpService.save(entry);
        // 获取保存的实体
        wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(true, BaffleFailTmp::getInterfaceId, entry.getInterfaceId());
        BaffleFailTmp one = failTmpService.getOne(wrapper);
        // 组装 url
        StringBuffer resUrlSb = new StringBuffer();
        resUrlSb.append(message_path_prefix);
        resUrlSb.append(baffleInterface.getUri());
        resUrlSb.append(CommonConstant.uri_spilt);
        resUrlSb.append(CommonConstant.fail);
        resUrlSb.append(one.getId());
        resUrlSb.append(CommonConstant.type_spilt);
        resUrlSb.append(resType);

        FileUtil.writeUtf8String(resRead, resUrlSb.toString());

        one.setResTmpUrl(resUrlSb.toString());
        // 更新
        failTmpService.saveOrUpdate(one);
        return ResultVo.getResult(ExceptionEnums.SUCCESS);
    }

    @RequestMapping("/del")
    @ResponseBody
    public ResultVo del(@RequestBody Collection<String> idList) {
        // 删除
        QueryWrapper<BaffleFailTmp> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(!CollectionUtils.isEmpty(idList), BaffleFailTmp::getId, idList);
        List<BaffleFailTmp> oldList = failTmpService.list(wrapper);
        boolean remove = failTmpService.remove(wrapper);
        if (remove && !CollectionUtils.isEmpty(oldList)) {
            oldList.stream().forEach(msg -> {
                FileUtil.del(msg.getResTmpUrl());
            });
        }
        return ResultVo.getResult(remove ? ExceptionEnums.SUCCESS : ExceptionEnums.DO_FAIL);
    }

}

